/*------------------------------------------------------------------------
 *  Copyright (C) 2011  Luis M. de la Cruz
 *
 *  This file is part of TUNA
 *
 *  TUNA is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  TUNA is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ------------------------------------------------------------------------*/

#ifndef _DIAGONAL_H_
#define _DIAGONAL_H_

#include "Storage/SparseMatrix.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

namespace Tuna {

  template <typename T, int Dim> class Diagonal;

/*!
 *  Specialization for Diagonal matriz from 1D problems.  
 */
  template <typename T>
  struct Typeinfo <Diagonal<T, 1> > {
    typedef T prec_t;
    enum { Dim = 1 };
  };

/*!
 *  Specialization for Diagonal matriz from 2D problems.  
 */
  template <typename T>
  struct Typeinfo <Diagonal<T, 2> > {
    typedef T prec_t;
    enum { Dim = 2 };
  };

/*!
 *  Specialization for Diagonal matriz from 3D problems.  
 */
  template <typename T>
  struct Typeinfo <Diagonal<T, 3> > {
    typedef T prec_t;
    enum { Dim = 3 };
  };

/*! 
 ***************************************************************************
 *  Adaptor for Diagonal matrices coming from FVM discretization.
 *  \author  Luis M. de la Cruz [ Sun Jan 20 14:16:36 GMT 2011 ]
 ***************************************************************************
 */
template<class Tprec, int Dim>
class Diagonal : public SparseMatrix<Diagonal<Tprec, Dim> >  {
  
  using SparseMatrix< Diagonal< Tprec, Dim > >::store; 
  using SparseMatrix< Diagonal< Tprec, Dim > >::rows; 
  using SparseMatrix< Diagonal< Tprec, Dim > >::cols; 

 public:

  Diagonal() : SparseMatrix<Diagonal<Tprec, Dim> >() { }
  ~Diagonal() {}

  bool print() {
    std::cout << " Diagonal < " << Dim << "D > >"
	      << "\n +-----+";
  }

  inline bool allocateMemory( ) { }

  inline bool allocateMemory(unsigned int e1) {
    ndiag = 2 * Dim + 1;
    rows = ndiag;
    store.resize(ndiag);
    for(int i = 0; i < ndiag; i++)
      store(i).resize(e1);
  };

  inline bool allocateMemory(unsigned int e1, unsigned int e2) {
    ndiag = 2 * Dim + 1;
    rows = ndiag;
    store.resize(ndiag);
    for(int i = 0; i < ndiag; i++)
      store(i).resize(e1, e2);
  };

  inline bool allocateMemory(unsigned int e1, unsigned int e2, unsigned int e3) {
    ndiag = 2 * Dim + 1;
    rows = ndiag;
    store.resize(ndiag);
    for(int i = 0; i < ndiag; i++)
      store(i).resize( e1, e2, e3);
  };

  inline bool resize(unsigned int e1);
  inline bool resize(unsigned int e1, unsigned int e2);
  inline bool resize(unsigned int e1, unsigned int e2, unsigned int e3);

  inline bool assignMatrix(SparseMatrix<Diagonal<Tprec, Dim> > & other);

  string getName() { return " SparseMatrix<Diagonal> ";  }

protected:    
    unsigned int ndiag;

private:

};
  
} //  Tuna namespace
 
#endif // _DIAGONAL_H_







